//
//  CLDefine.h
//  CargoDd
//
//  Created by CCYQ on 21/7/8.
//  Copyright © 2021年 lhc. All rights reserved.
//

#ifndef Define_h
#define Define_h


#define SCREENWIDTH [UIScreen mainScreen].bounds.size.width
#define SCREENHEIGHT [UIScreen mainScreen].bounds.size.height
#define SCREEN_MAX_LENGTH (MAX(SCREENWIDTH, SCREENHEIGHT))
#define SCREEN_MIN_LENGTH (MIN(SCREENWIDTH, SCREENHEIGHT))
#define SCREENBOUNDS ([[UIScreen mainScreen] bounds])

#define IS_IPAD ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
#define IS_IPHONE ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
#define IS_IPHONE_4_OR_LESS (IS_IPHONE && SCREEN_MAX_LENGTH < 568.0)
#define IS_IPHONE_5 (IS_IPHONE && SCREEN_MAX_LENGTH == 568.0)
#define IS_IPHONE_6 (IS_IPHONE && SCREEN_MAX_LENGTH == 667.0)
#define IS_IPHONE_6P (IS_IPHONE && SCREEN_MAX_LENGTH == 736.0)
#define IS_IPHONE_X (IS_IPHONE && SCREEN_MAX_LENGTH >= 812.0)

#define iOS7Later ([UIDevice currentDevice].systemVersion.floatValue >= 7.0f)
#define iOS8Later ([UIDevice currentDevice].systemVersion.floatValue >= 8.0f)
#define iOS9Later ([UIDevice currentDevice].systemVersion.floatValue >= 9.0f)
#define iOS9_1Later ([UIDevice currentDevice].systemVersion.floatValue >= 9.1f)

/// 导航条高度
#define CL_APPLICATION_TOP_BAR_HEIGHT (IS_IPHONE_X?88.0f:64.0f)
/// tabBar高度
#define CL_APPLICATION_TAB_BAR_HEIGHT (IS_IPHONE_X?83.0f:49.0f)
/// 工具条高度 (常见的高度)
#define CL_APPLICATION_TOOL_BAR_HEIGHT_44  44.0f
#define CL_APPLICATION_TOOL_BAR_HEIGHT_49  49.0f

/// 状态栏是否隐藏，状态栏隐藏时（如开播页面），动态获取高度恒为0
#define IS_HIDDEN_STATUSBAR ([[UIApplication sharedApplication] isStatusBarHidden])
/// 状态栏不隐藏时，刘海屏状态栏高度
#define X_TOP_NORMAL ({\
    CGFloat statusbarHeight = 44.0; \
    if (@available(iOS 13.0, *)) { \
        statusbarHeight = [UIApplication sharedApplication].delegate.window.windowScene.statusBarManager.statusBarFrame.size.height; \
    }\
    if (statusbarHeight == 0) {\
        statusbarHeight = [[UIApplication sharedApplication] statusBarFrame].size.height; \
    }\
    statusbarHeight; \
})
///  刘海屏状态栏高度
#define X_TOP (!IS_HIDDEN_STATUSBAR ? X_TOP_NORMAL : 44)
#define X_BOTTOM 34
#define AUTO_TOP (IS_IPHONE_X?X_TOP:0)
#define AUTO_BOTTOM (IS_IPHONE_X?X_BOTTOM:0)
/// 状态栏高度
//#define CL_APPLICATION_STATUS_BAR_HEIGHT (IS_IPHONE_X?44:20.0f)
#define STATUSBAR_HEIGHT          (IS_IPHONE_X?44.0:20.0)
#define NAVBAR_HEIGHT             ((IS_IPHONE_X?44.0:20.0)+44.0) //状态栏+Navi
#define TABBAR_HEIGHT             CL_APPLICATION_TAB_BAR_HEIGHT
#define SAFEAREA_BOTTOMHEIGHT   34.0  ///< 底部安全区域高度
#define NavgationBarHeight          NAVBAR_HEIGHT
/// 这针对iPhone6为标准适配高度，全屏且不滚动，且有带tabbar和导航栏的页面，需要先减去导航栏高度、底部Tabbar高度（基本不会用到）
#define HEIGHT_NAVTABBAR(R) ((R)*((SCREEN_HEIGHT-NAVBAR_HEIGHT-TABBAR_HEIGHT)/(667.0-NAVBAR_HEIGHT-TABBAR_HEIGHT)))
/// 这针对iPhone6为标准适配宽度
#define WIDTH(R) ((R)*(SCREENWIDTH/375.0))
/// 这针对iPhone6为标准适配高度
#define HEIGHT(R) ( IS_IPHONE_X?R:((R)*(SCREENHEIGHT/667.0)) )
/// 这针对iPhone6为标准适配高度，全屏且不滚动，且只有带导航栏的页面，需要先减去导航栏高度
#define HEIGHT_NAV(R) ((R)*((SCREENHEIGHT-NAVBAR_HEIGHT)/(667.0-NAVBAR_HEIGHT)))
/// 这针对iPhone6为标准适配高度，全屏且不滚动，且有带tabbar和导航栏的页面，需要先减去导航栏高度、底部Tabbar高度（基本不会用到）
#define HEIGHT_NAVTABBAR(R) ((R)*((SCREEN_HEIGHT-NAVBAR_HEIGHT-TABBAR_HEIGHT)/(667.0-NAVBAR_HEIGHT-TABBAR_HEIGHT)))

#pragma mark - Font Size
/// 最小字体
#define FONT_MIN_SIZE 12.5
/// 这针对iPhone6为标准适配
#define FONT(s)       [UIFont cl_systemFontOfSize:FONTSIZE(s)]
#define FONT_BOLD(s)   [UIFont cl_boldSystemFontOfSize:FONTSIZE(s)]
#define FONT_LIGHT(s)  [UIFont cl_lightSystemFontOfSize:FONTSIZE(s)]
/// 字体大小转换，<=12的字体不换算
#define FONTSIZE(s) ( IS_IPHONE_X?s:((s<FONT_MIN_SIZE)?s:((s)*SCREEN_MAX_LENGTH/667.0)) )

#pragma mark - 基础颜色
#define RGBACOLOR(r,g,b,a) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:(a)]
#define RGB(r, g, b) RGBACOLOR(r, g, b, 1.0f)

#define HEXRGB(rgbValue) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]
#define HEXRGBALPHA(rgbValue,a) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:(a)]



//定义个文档存储沙盘路径[NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]
#define CLDocumentPath(path) [NSTemporaryDirectory() stringByAppendingString:path]
//定义个用户存储中心句柄
#define CLUserDefauleSave [NSUserDefaults standardUserDefaults]
//定义个用户通知中心句柄
#define Notifier [NSNotificationCenter defaultCenter]

#define ITTAssert(condition, ...)                                       \
do {                                                                      \
if (!(condition)) {                                                     \
[[NSAssertionHandler currentHandler]                                  \
handleFailureInFunction:[NSString stringWithUTF8String:__PRETTY_FUNCTION__] \
file:[NSString stringWithUTF8String:__FILE__]  \
lineNumber:__LINE__                                  \
description:__VA_ARGS__];                             \
}                                                                       \
} while(0)

#define NotNull(object)  [object isKindOfClass:[NSNull class]]?@"":object

//判断是真机还是模拟器
#if TARGET_OS_IPHONE
//iPhone Device
#endif

#if TARGET_IPHONE_SIMULATOR
//iPhone Simulator
#endif


//----------------------视图相关----------------------------
//设置需要粘贴的文字或图片
#define PasteString(string)   [[UIPasteboard generalPasteboard] setString:string];
#define PasteImage(image)     [[UIPasteboard generalPasteboard] setImage:image];

//得到视图的left top的X,Y坐标点
#define VIEW_TX(view) (view.frame.origin.x)
#define VIEW_TY(view) (view.frame.origin.y)

//得到视图的right bottom的X,Y坐标点
#define VIEW_BX(view) (view.frame.origin.x + view.frame.size.width)
#define VIEW_BY(view) (view.frame.origin.y + view.frame.size.height )

//得到视图的尺寸:宽度、高度
#define VIEW_W(view) (view.frame.size.width)
#define VIEW_H(view) (view.frame.size.height)
//得到frame的X,Y坐标点
#define FRAME_TX(frame) (frame.origin.x)
#define FRAME_TY(frame) (frame.origin.y)
//得到frame的宽度、高度
#define FRAME_W(frame)  (frame.size.width)
#define FRAME_H(frame)  (frame.size.height)
//----------------------视图相关----------------------------



//----------------------输出----------------------
#ifdef DEBUG
//#define NSLog(FORMAT, ...) fprintf(stderr,"\n╭═════════════════════════════════════════════════════════╮ \n║方法:%s 行:%d \n║详情:%s\n╰═════════════════════════════════════════════════════════╯\n", __FUNCTION__, __LINE__, [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);

#define NSLog(format, ...) do {                                 \
fprintf(stderr, "%s\t%s:%d\n",                                  \
[[NSString stringWithFormat:format, ##__VA_ARGS__] UTF8String], \
__func__,                                                       \
__LINE__                                                        \
);                                                              \
} while (0)
#else
#define NSLog(...);
#endif

#ifdef DEBUG
#define JSLog(format, ...) do {                                 \
fprintf(stderr, "[js]:%s\n",[[NSString stringWithFormat:format, ##__VA_ARGS__] UTF8String]);\
} while (0)
#else
#define NSLog(...);
#endif


#define KRect(x,y,w,h)  CGRectMake(x, y, w, h)

#define NSLogRect(rect) NSLog(@"%s x:%.4f, y:%.4f, w:%.4f, h:%.4f", #rect, rect.origin.x, rect.origin.y, rect.size.width, rect.size.height)

#define NSLogInset(inset) NSLog(@"%s top:%.4f, left:%.4f, right:%.4f, bottom:%.4f", #inset, inset.top, inset.left, inset.right, inset.bottom)

#define NSLogSize(size) NSLog(@"%s w:%.4f, h:%.4f", #size, size.width, size.height)
#define NSLogPoint(point) NSLog(@"%s x:%.4f, y:%.4f", #point, point.x, point.y)
//----------------------输出----------------------





// 定义个自1900年的时间格式句柄
#define kDateSince1900(v,f,d) NSDateFormatter *df = [[NSDateFormatter alloc] init];\
df.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];\
df.dateFormat = d;\
NSTimeInterval timeInterval = (v/1000000);\
NSDate *qt = [NSDate dateWithTimeInterval:timeInterval sinceDate:[df dateFromString:f]];\
df.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:8*3600]; \
return [df stringFromDate:qt];\
// 定义个自1970年的时间格式句柄
#define kDateSince1970(v,format,ret) \
{ NSDateFormatter *df = [[NSDateFormatter alloc] init];\
df.dateFormat = format;\
NSDate *qt = [NSDate dateWithTimeIntervalSince1970:v];\
ret = [df stringFromDate:qt];}


//检测数组是否有东西，有东西就是YES,没有东西或者数组不存在就为NO
#define ARR_ISNOT_NIL(arr) ([arr isKindOfClass:[NSArray class]]?(arr?(arr.count>0?YES:NO):NO):NO)

#define DICT_ISNOT_NIL(responseDict) ([responseDict isKindOfClass:[NSDictionary class]]?(responseDict?(responseDict.count>0?YES:NO):NO):NO)

//屏幕分辨率
#define iPhone4s ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(640, 960), [[UIScreen mainScreen] currentMode].size) : NO)

#define iPhone5 ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(640, 1136), [[UIScreen mainScreen] currentMode].size) : NO)

#define isRetinas ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(640, 960), [[UIScreen mainScreen] currentMode].size) : NO)
#define iPhone5 ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(640, 1136), [[UIScreen mainScreen] currentMode].size) : NO)

#define iPhone6 ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? (CGSizeEqualToSize(CGSizeMake(750, 1334), [[UIScreen mainScreen] currentMode].size) || CGSizeEqualToSize(CGSizeMake(640, 1136), [[UIScreen mainScreen] currentMode].size)) : NO)

#define iPhone6plus ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? (CGSizeEqualToSize(CGSizeMake(1125, 2001), [[UIScreen mainScreen] currentMode].size) || CGSizeEqualToSize(CGSizeMake(1242, 2208), [[UIScreen mainScreen] currentMode].size)) : NO)

#define ISPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)


//基于4s兼容值转化,根据屏幕高来拿比例，(当前高 * value)/480.
#define COMPATIBLEVALUE(value) ([UIScreen mainScreen].bounds.size.height * value)/480.

//基于4s兼容值转化,根据屏幕高来拿比例，(当前高 * value)/320.
#define COMPATIBLE_W_VALUE(value) ([UIScreen mainScreen].bounds.size.width * value)/320.

//增加点击事件
#define ADDVIEWTAG(View,Selector)\
if([View isKindOfClass:[UIButton class]])\
{\
[(UIButton *)View addTarget:self action:@selector(Selector) forControlEvents:UIControlEventTouchUpInside];\
} else{\
UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(Selector)];\
View.userInteractionEnabled = YES;\
[View addGestureRecognizer:tap];\
}\

//判断类型
#define kLHZ_JudgeObjectIsArray(array) (array && [array isKindOfClass:[NSArray class]] && array.count>0)//判断集合
#define kLHZ_JudeObjectIsNSString(string) (string && [string isKindOfClass:[NSString class]] && string.length>0)//判断字符
#define kLHZ_JudgeObjectIsDictionary(dictionary) (dictionary && [dictionary isKindOfClass:[NSDictionary class]] && dictionary.count>0)//判断字典
#define kLHZ_JudgeObjectIsInteger(int) (int && [int respondsToSelector:@selector(integerValue)])//判断是否是整数

//获取图片
#define KImage(x)  [UIImage imageNamed:x]


//类型转换
//integer 转换为string
#define IntegerToString(x)  [NSString stringWithFormat:@"%ld",(long)x]
//double 转换成string
#define DoubleToString(x)   [NSString stringWithFormat:@"%f",x]

//num 转换成string
#define NumToString(x)   [NSString stringWithFormat:@"%@",x]

//空字符串转“”
#define StrIsNotNull(str) ([str isKindOfClass:[NSString class]]?(str.length>0?str:@""):@"")
//弱引用
#define WS(weakSelf)  __weak __typeof(&*self)weakSelf = self;


#define IOS7_OR_LATER    ([[[UIDevice currentDevice] systemVersion] compare:@"7.0"] != NSOrderedAscending )

#define IOS8_OR_LATER    ([[[UIDevice currentDevice] systemVersion] compare:@"8.0"] != NSOrderedAscending )

#define USERTOKEN [UserInfoClient shareUserInfo].userToken

//#define SetImageWithStr(iv,str) [iv setImageWithURL:[NSURL URLWithString:str] placeholderImage:nil]

#define SetImageWithStr(iv,str) \
if ([str isKindOfClass:[NSString class]]) {\
if ([NSURL URLWithString:str]) {\
[iv setImageWithURL:[NSURL URLWithString:str] placeholderImage:nil];\
}else{\
UIImage * image = [UIImage imageWithContentsOfFile:str];\
if (image) {\
iv.image = image;\
}else{\
iv.image= nil;\
NSLog(@"error:%s==>%@",__FUNCTION__,str);\
}\
}\
}else if ([str isKindOfClass:[UIImage class]]) {\
iv.image = (UIImage *)str;\
}else{\
iv.image= nil;\
NSLog(@"error:%s==>%@",__FUNCTION__,str);\
}\


#define SetImageWithStrPlaceholdImg(iv,str,placeholdImg) \
if ([str isKindOfClass:[NSString class]]) {\
if ([NSURL URLWithString:str]) {\
[iv setImageWithURL:[NSURL URLWithString:str] placeholderImage:placeholdImg];\
}else{\
UIImage * image = [UIImage imageWithContentsOfFile:str];\
if (image) {\
iv.image = image;\
}else{\
iv.image= placeholdImg;\
NSLog(@"error:%s==>%@",__FUNCTION__,str);\
}\
}\
}else if ([str isKindOfClass:[UIImage class]]) {\
iv.image = (UIImage *)str;\
}else{\
iv.image= placeholdImg;\
NSLog(@"error:%s==>%@",__FUNCTION__,str);\
}\


#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)


//#pragma clang diagnostic push
//#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"
//
//
//
//#pragma clang diagnostic pop

// 打印请求错误信息
#define CLLogError(error) NSLog(@"Error: %@", error)
// 销毁打印
#define CLDealloc NSLog(@"+++ %@  销毁了 +++",[self class])

/// 文字颜色
/// #56585f
#define CL_MAIN_TEXT_COLOR_1 HEXRGB(0xB2B2B2)
/// #9CA1B2
#define CL_MAIN_TEXT_COLOR_2 HEXRGB(0x20DB1F)
/// #FE583E
#define CL_MAIN_TEXT_COLOR_3 HEXRGB(0xFE583E)
/// #0ECCCA
#define CL_MAIN_TEXT_COLOR_4 HEXRGB(0x0ECCCA)
/// #3C3E44
#define CL_MAIN_TEXT_COLOR_5 HEXRGB(0x3C3E44)

#pragma mark - PATH

#define HomePath NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES)[0]
#define CachePath NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0]
#define CLDocumentDirectory [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES) lastObject]
#define DocumentPath [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject]
#define TempPath NSTemporaryDirectory()

// 系统放大倍数
#define CLScale [[UIScreen mainScreen] scale]

// 设置图片
#define CLImageNamed(__imageName) [UIImage imageNamed:__imageName]

//// --------------------  下面是公共配置  --------------------

/// 微信项目重要数据备份的文件夹名称（Documents/CLAppDoc）利用NSFileManager来访问
#define CLAPP_DOC_NAME  @"CLAppDoc"

/// 微信项目轻量数据数据备份的文件夹（Library/Caches/CLAppCache）利用NSFileManager来访问
#define CLAPP_CACHE_NAME  @"CLAppCache"

#define UIColorFromRGB(rgbValue)                [UIColor colorWithRed : ((float)((rgbValue & 0xFF0000) >> 16)) / 255.0f green : ((float)((rgbValue & 0xFF00) >> 8)) / 255.0f blue : ((float)(rgbValue & 0xFF)) / 255.0f alpha : 1.0f]
#define UIColorFromRGBAndAlpha(rgbValue,a)                [UIColor colorWithRed : ((float)((rgbValue & 0xFF0000) >> 16)) / 255.0f green : ((float)((rgbValue & 0xFF00) >> 8)) / 255.0f blue : ((float)(rgbValue & 0xFF)) / 255.0f alpha : a]
/// 根据hex 获取颜色
#define CLColorWithHexString(__hexString__) ([UIColor colorWithHexString:__hexString__])

/// ---- YYWebImage Option
/// 手动设置image
#define CLWebImageOptionManually (YYWebImageOptionAllowInvalidSSLCertificates|YYWebImageOptionAllowBackgroundTask|YYWebImageOptionSetImageWithFadeAnimation|YYWebImageOptionAvoidSetImage)


/// 自动设置Image
#define CLWebImageOptionAutomatic (YYWebImageOptionAllowInvalidSSLCertificates|YYWebImageOptionProgressiveBlur | YYWebImageOptionSetImageWithFadeAnimation | YYWebImageOptionRefreshImageCache)//(YYWebImageOptionAllowInvalidSSLCertificates|YYWebImageOptionAllowBackgroundTask)
//YYWebImageOptionAllowInvalidSSLCertificates|YYWebImageOptionAllowBackgroundTask|YYWebImageOptionAvoidSetImage|YYWebImageOptionSetImageWithFadeAnimation

// 是否为空对象
#define CLObjectIsNil(__object)  ((nil == __object) || [__object isKindOfClass:[NSNull class]])

// 字符串为空
#define CLStringIsEmpty(__string) ((__string.length == 0) || CLObjectIsNil(__string))

// 字符串不为空
#define CLStringIsNotEmpty(__string)  (!CLStringIsEmpty(__string))

// 数组为空
#define CLArrayIsEmpty(__array) ((CLObjectIsNil(__array)) || (__array.count==0))

/// 适配iPhone X + iOS 11
#define  CLAdjustsScrollViewInsets_Never(__scrollView)\
do {\
_Pragma("clang diagnostic push")\
_Pragma("clang diagnostic ignored \"-Warc-performSelector-leaks\"")\
if ([__scrollView respondsToSelector:NSSelectorFromString(@"setContentInsetAdjustmentBehavior:")]) {\
NSMethodSignature *signature = [UIScrollView instanceMethodSignatureForSelector:@selector(setContentInsetAdjustmentBehavior:)];\
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];\
NSInteger argument = 2;\
invocation.target = __scrollView;\
invocation.selector = @selector(setContentInsetAdjustmentBehavior:);\
[invocation setArgument:&argument atIndex:2];\
[invocation retainArguments];\
[invocation invoke];\
}\
_Pragma("clang diagnostic pop")\
} while (0)


/// AppDelegate
#define CLSharedAppDelegate ((AppDelegate *)[UIApplication sharedApplication].delegate)
/// viewController 跳转可用
#define CLNavigationService ((AppDelegate *)[UIApplication sharedApplication].delegate).services
/// 全局细下滑线颜色 以及分割线颜色
#define CLGlobalBottomLineColor     [UIColor colorWithHexString:@"#D9D9D9"]

/// 整个应用的视图的背景色 BackgroundColor
#define CL_MAIN_BACKGROUNDCOLOR [UIColor colorWithHexString:@"#EFEFF4"]
/// 整个应用的分割线颜色
#define CL_MAIN_LINE_COLOR_1 [UIColor colorWithHexString:@"#D9D8D9"]


// KVO获取监听对象的属性 有自动提示
// 宏里面的#，会自动把后面的参数变成c语言的字符串
#define CLKeyPath(objc,keyPath) @(((void)objc.keyPath ,#keyPath))

// 颜色
#define CLColor(r, g, b) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1.0]
// 颜色+透明度
#define CLColorAlpha(r, g, b, a) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:a]
// 随机色
#define CLRandomColor CLColor(arc4random_uniform(256), arc4random_uniform(256), arc4random_uniform(256))
// 根据rgbValue获取对应的颜色
#define CLColorFromRGB(__rgbValue) [UIColor colorWithRed:((float)((__rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((__rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(__rgbValue & 0xFF))/255.0 alpha:1.0]

#define CLColorFromRGBAlpha(rgbValue, a) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:(a)]

#define NULLString(string) ((![string isKindOfClass:[NSString class]])||[string isEqualToString:@""] || (string == nil) || [string isEqualToString:@""] || [string isKindOfClass:[NSNull class]]||[[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] length]==0 || [string isEqualToString:@"(null)"])

#define StrNilHolder(str,holder)   ([str isKindOfClass:[NSString class]]?([str isEqualToString:@""]?holder:str):holder)   //字符串为空字符，即使用默认holder


// IOS版本
#define CLIOSVersion ([[[UIDevice currentDevice] systemVersion] floatValue])


/// 设置系统的字体大小（YES：粗体 NO：常规）
#define CLFont(__size__,__bold__) ((__bold__)?([UIFont boldSystemFontOfSize:__size__]):([UIFont systemFontOfSize:__size__]))

/// 极细体
#define CLUltralightFont(__size__) ((CLIOSVersion<9.0)?CLFont(__size__ , YES):[UIFont cl_fontForPingFangSC_UltralightFontOfSize:__size__])

/// 纤细体
#define CLThinFont(__size__)       ((CLIOSVersion<9.0)?CLFont(__size__ , YES):[UIFont cl_fontForPingFangSC_ThinFontOfSize:__size__])

/// 细体
#define CLLightFont(__size__)      ((CLIOSVersion<9.0)?CLFont(__size__ , YES):[UIFont cl_fontForPingFangSC_LightFontOfSize:__size__])

// 中等
#define CLMediumFont(__size__)     ((CLIOSVersion<9.0)?CLFont(__size__ , YES):[UIFont cl_fontForPingFangSC_MediumFontOfSize:__size__])

// 常规
#define CLRegularFont(__size__)    ((CLIOSVersion<9.0)?CLFont(__size__ , NO):[UIFont cl_fontForPingFangSC_RegularFontOfSize:__size__])

/** 中粗体 */
#define CLSemiboldFont(__size__)   ((CLIOSVersion<9.0)?CLFont(__size__ , YES):[UIFont cl_fontForPingFangSC_SemiboldFontOfSize:__size__])

#define SYNTHESIZE_SINGLETON_FOR_CLASS_HEADER(__CLASSNAME__)    \
    \
    + (__CLASSNAME__*) sharedInstance;


#define SYNTHESIZE_SINGLETON_FOR_CLASS(__CLASSNAME__)    \
    + (__CLASSNAME__ *)sharedInstance\
    {\
        static __CLASSNAME__ *shared##className = nil;\
        static dispatch_once_t onceToken; \
        dispatch_once(&onceToken, ^{ \
            shared##className = [[super allocWithZone:NULL] init]; \
    }); \
    return shared##className; \
}\
+ (id)allocWithZone:(NSZone*)zone {\
    return [self sharedInstance];\
}\
- (id)copyWithZone:(NSZone *)zone {\
    return self;\
}

#pragma mark - Safe Main Queue

// Be careful of dead lock
static inline void dispatch_main_safe_sync(void (^block)(void)) {
    if (dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL) == dispatch_queue_get_label(dispatch_get_main_queue())) {
        block();
    } else {
        dispatch_async(dispatch_get_main_queue(), block);
    }
}

static inline void dispatch_main_safe_async(void (^block)(void)) {
    if (dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL) == dispatch_queue_get_label(dispatch_get_main_queue())) {
        block();
    } else {
        dispatch_async(dispatch_get_main_queue(), block);
    }
}


#pragma mark - Convienence

#define IsCurrentWebView(webView)  [[CLWebViewManager sharedInstance] isCurrentWebView:webView]

#define CLMainVC  [CLVCMain sharedInstance]
#define CLWebManager  [CLWebViewManager sharedInstance]

#define WEAK_SELF __weak __typeof(&*self)weakSelf = self

#define STRONG_SELF __strong typeof(*&weakSelf)strongSelf = weakSelf;\
if (!strongSelf) {\
return;\
}

#define CLSafeExecuteBlock(__CL_Block__, ...) { if (__CL_Block__) __CL_Block__(__VA_ARGS__); }

#define CLSafeReturnExeBlock(__CL_Block__, ...) { if (__CL_Block__) return __CL_Block__(__VA_ARGS__); }

#define CLSafeMainExecuteBlock(__CL_Block__, ...) { if (__CL_Block__) dispatch_main_safe_async(^{ __CL_Block__(__VA_ARGS__);}); }

/*
 NSCoding
 #import <objc/runtime.h>
 #import <YYKit/YYClassInfo.h>
 */
#define CLEncodeMethod \
- (id)initWithCoder:(NSCoder *)aDecoder {\
    if (self = [super initWithCoder:aDecoder]) {\
        unsigned int count;\
        objc_property_t *properties = class_copyPropertyList([self class], &count);\
        if (properties) {\
            for (unsigned int i = 0; i < count; i++) {\
                objc_property_t property = properties[i];\
                YYClassPropertyInfo *info = [[YYClassPropertyInfo alloc] initWithProperty:property];\
                if (info.name && info.cls) {\
                    id value = [aDecoder decodeObjectOfClass:info.cls forKey:info.name];\
                    if (value) {\
                        [self setValue:value forKey:info.name];\
                    }\
                }\
            }\
            free(properties);\
        }\
    }\
    return self;\
}\
- (void)encodeWithCoder:(NSCoder *)aCoder{\
    unsigned int count;\
    objc_property_t *properties = class_copyPropertyList([self class], &count);\
    if (properties) {\
        for (unsigned int i = 0; i < count; i++) {\
            objc_property_t property = properties[i];\
            YYClassPropertyInfo *info = [[YYClassPropertyInfo alloc] initWithProperty:property];\
            if (info.name) {\
                id value = [self valueForKey:info.name];\
                if ([value conformsToProtocol:@protocol(NSCoding)]) {\
                    [aCoder encodeObject:value forKey:info.name];\
                }\
            }\
        }\
        free(properties);\
    }\
}


#endif /* Define_h */
